home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 December / PCWorld_2007-12_cd.bin / v cisle / htttrack / httrack-3.41-3.exe / {app} / src / htsbauth.c < prev    next >
C/C++ Source or Header  |  2006-05-20  |  13KB  |  415 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: httrack.c subroutines:                                 */
  34. /*       basic authentication: password storage                 */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38. /* Internal engine bytecode */
  39. #define HTS_INTERNAL_BYTECODE
  40.  
  41. #include "htsbauth.h"
  42.  
  43. /* specific definitions */
  44. #include "htsglobal.h"
  45. #include "htslib.h"
  46.  
  47. /* END specific definitions */
  48.  
  49. // gestion des cookie
  50. // ajoute, dans l'ordre
  51. // !=0 : erreur
  52. int cookie_add(t_cookie* cookie,char* cook_name,char* cook_value,char* domain,char* path) {
  53.     char buffer[8192];
  54.   char* a=cookie->data;
  55.   char* insert;
  56.   char cook[16384];
  57.   // effacer Θventuel cookie en double
  58.   cookie_del(cookie,cook_name,domain,path);
  59.   if ((int)strlen(cook_value)>1024) return -1;                              // trop long
  60.   if ((int)strlen(cook_name)>256) return -1;                                // trop long
  61.   if ((int)strlen(domain)>256) return -1;                                   // trop long
  62.   if ((int)strlen(path)>256) return -1;                                     // trop long
  63.   if ((int)(
  64.     strlen(cookie->data)
  65.     +strlen(cook_value)
  66.     +strlen(cook_name)
  67.     +strlen(domain)
  68.     +strlen(path)
  69.     +256
  70.     ) > cookie->max_len) return -1;               // impossible d'ajouter
  71.  
  72.   insert=a;          // insΘrer ici
  73.   while (*a) {
  74.     if ( strlen(cookie_get(buffer, a,2)) <  strlen(path) )      // long. path (le + long est prioritaire)
  75.       a=cookie->data+strlen(cookie->data);    // fin
  76.     else {
  77.       a=strchr(a,'\n');     // prochain champ
  78.       if (a==NULL)
  79.         a=cookie->data+strlen(cookie->data);    // fin
  80.       else
  81.         a++;
  82.       while(*a=='\n') a++;
  83.       insert=a;          // insΘrer ici
  84.     }
  85.   }
  86.   // construction du cookie
  87.   strcpybuff(cook,domain);
  88.   strcatbuff(cook,"\t");
  89.   strcatbuff(cook,"TRUE");
  90.   strcatbuff(cook,"\t");
  91.   strcatbuff(cook,path);
  92.   strcatbuff(cook,"\t");
  93.   strcatbuff(cook,"FALSE");
  94.   strcatbuff(cook,"\t");
  95.   strcatbuff(cook,"1999999999");
  96.   strcatbuff(cook,"\t");
  97.   strcatbuff(cook,cook_name);
  98.   strcatbuff(cook,"\t");
  99.   strcatbuff(cook,cook_value);
  100.   strcatbuff(cook,"\n");
  101.   if (!( ((int) strlen(cookie->data) + (int) strlen(cook)) < cookie->max_len)) return -1;      // impossible d'ajouter
  102.   cookie_insert(insert,cook);
  103. #if DEBUG_COOK
  104.   printf("add_new cookie: name=\"%s\" value=\"%s\" domain=\"%s\" path=\"%s\"\n",cook_name,cook_value,domain,path);
  105.   //printf(">>>cook: %s<<<\n",cookie->data);
  106. #endif
  107.   return 0;
  108. }
  109.  
  110. // effacer cookie si existe
  111. int cookie_del(t_cookie* cookie,char* cook_name,char* domain,char* path) {
  112.   char *a,*b;
  113.   b=cookie_find(cookie->data,cook_name,domain,path);
  114.   if (b) {
  115.     a=cookie_nextfield(b);
  116.     cookie_delete(b,(int) (a - b));
  117. #if DEBUG_COOK
  118.     printf("deleted old cookie: %s %s %s\n",cook_name,domain,path);
  119. #endif
  120.   }
  121.   return 0;
  122. }
  123.  
  124. // rechercher cookie α partir de la position s (par exemple s=cookie.data)
  125. // renvoie pointeur sur ligne, ou NULL si introuvable
  126. // path est alignΘ α droite et cook_name peut Ωtre vide (chercher alors tout cookie)
  127. // .doubleclick.net    TRUE    /    FALSE    1999999999    id    A
  128. char* cookie_find(char* s,char* cook_name,char* domain,char* path) {
  129.     char buffer[8192];
  130.   char* a=s;
  131.   while (*a) {
  132.     int t;
  133.     if (strnotempty(cook_name)==0)
  134.       t=1;                      // accepter par dΘfaut
  135.     else
  136.       t=( strcmp(cookie_get(buffer, a,5),cook_name)==0 );     // tester si mΩme nom
  137.     if (t) {  // mΩme nom ou nom qualconque
  138.       //
  139.       char* chk_dom=cookie_get(buffer,a,0);       // domaine concernΘ par le cookie
  140.       if ((int) strlen(chk_dom) <= (int) strlen(domain)) {
  141.         if ( strcmp(chk_dom,domain+strlen(domain)-strlen(chk_dom))==0 ) {  // mΩme domaine
  142.           //
  143.           char* chk_path=cookie_get(buffer,a,2);       // chemin concernΘ par le cookie
  144.           if ((int) strlen(chk_path) <= (int) strlen(path)) {
  145.             if (strncmp(path,chk_path,strlen(chk_path))==0 ) { // mΩme chemin
  146.               return a;
  147.             }
  148.           }
  149.         }
  150.       }
  151.     }
  152.     a=cookie_nextfield(a);
  153.   }
  154.   return NULL;
  155. }
  156.  
  157. // renvoie prochain champ
  158. char* cookie_nextfield(char* a) {
  159.   char* b=a;
  160.   a=strchr(a,'\n');     // prochain champ
  161.   if (a==NULL)
  162.     a=b+strlen(b);    // fin
  163.   else
  164.     a++;
  165.   while(*a=='\n') a++;
  166.   return a;
  167. }
  168.  
  169. // lire cookies.txt
  170. // lire Θgalement (Windows seulement) les *@*.txt (cookies IE copiΘs)
  171. // !=0 : erreur
  172. int cookie_load(t_cookie* cookie, const char* fpath, const char* name) {
  173.     char catbuff[CATBUFF_SIZE];
  174.     char buffer[8192];
  175.  //  cookie->data[0]='\0';
  176.  
  177.   // Fusionner d'abord les Θventuels cookies IE
  178. #ifdef _WIN32
  179.   {
  180.     WIN32_FIND_DATAA find;
  181.     HANDLE h;
  182.     char  pth[MAX_PATH + 32];
  183.     strcpybuff(pth,fpath);
  184.     strcatbuff(pth,"*@*.txt");
  185.     h = FindFirstFileA((char*)pth,&find);
  186.     if (h != INVALID_HANDLE_VALUE) {
  187.       do {
  188.         if (!(find.dwFileAttributes  & FILE_ATTRIBUTE_DIRECTORY ))
  189.           if (!(find.dwFileAttributes  & FILE_ATTRIBUTE_SYSTEM )) {
  190.             FILE* fp=fopen(fconcat(catbuff, fpath, find.cFileName),"rb");
  191.             if (fp) {
  192.               char cook_name[256];
  193.               char cook_value[1000];
  194.               char domainpathpath[512];
  195.               char dummy[512];
  196.               //
  197.               char domain[256];           // domaine cookie (.netscape.com)
  198.               char path[256];             // chemin (/)
  199.               int cookie_merged=0;
  200.               //
  201.               // Read all cookies
  202.               while( ! feof(fp) ) {
  203.                 cook_name[0] = cook_value[0] = domainpathpath[0] 
  204.                   = dummy[0] = domain[0] = path[0] = '\0';
  205.                 linput(fp,cook_name,250);
  206.                 if ( ! feof(fp) ) {
  207.                   linput(fp,cook_value,250);
  208.                   if ( ! feof(fp) )  {
  209.                     int i;
  210.                     linput(fp,domainpathpath,500);
  211.                     /* Read 6 other useless values */
  212.                     for(i = 0 ; ! feof(fp) && i < 6 ; i++) {
  213.                       linput(fp,dummy,500);
  214.                     }
  215.                     if (strnotempty(cook_name) 
  216.                       && strnotempty(cook_value) 
  217.                       && strnotempty(domainpathpath)) {
  218.                       if (ident_url_absolute(domainpathpath,domain,path)>=0) {
  219.                         cookie_add(cookie,cook_name,cook_value,domain,path);
  220.                         cookie_merged=1;
  221.                       }
  222.                     }
  223.                   }
  224.                 }
  225.               }
  226.               fclose(fp);
  227.               if (cookie_merged)
  228.                 remove(fconcat(catbuff,fpath,find.cFileName));
  229.             }  // if fp
  230.           }
  231.       } while(FindNextFileA(h,&find));
  232.       FindClose(h);
  233.     }
  234.   }
  235. #endif
  236.   
  237.   // Ensuite, cookies.txt
  238.   {
  239.     FILE* fp = fopen(fconcat(catbuff, fpath, name),"rb");
  240.     if (fp) {
  241.       char BIGSTK line[8192];
  242.       while( (!feof(fp)) && (((int) strlen(cookie->data)) < cookie->max_len)) {
  243.         rawlinput(fp,line,8100);
  244.         if (strnotempty(line)) {
  245.           if (strlen(line)<8000) {
  246.             if (line[0]!='#') {
  247.               char domain[256];           // domaine cookie (.netscape.com)
  248.               char path[256];             // chemin (/)
  249.               char cook_name[256];        // nom cookie (MYCOOK)
  250.               char BIGSTK cook_value[8192];      // valeur (ID=toto,S=1234)
  251.               strcpybuff(domain,cookie_get(buffer,line,0));       // host
  252.               strcpybuff(path,cookie_get(buffer,line,2));         // path
  253.               strcpybuff(cook_name,cookie_get(buffer,line,5));    // name
  254.               strcpybuff(cook_value,cookie_get(buffer,line,6));   // value
  255. #if DEBUG_COOK
  256.               printf("%s\n",line);
  257. #endif
  258.               cookie_add(cookie,cook_name,cook_value,domain,path);
  259.             }
  260.           }
  261.         }
  262.       }
  263.       fclose(fp);
  264.       return 0;
  265.     }
  266.   }
  267.   return -1;
  268. }
  269.  
  270. // Θcrire cookies.txt
  271. // !=0 : erreur
  272. int cookie_save(t_cookie* cookie,char* name) {
  273.     char catbuff[CATBUFF_SIZE];
  274.   if (strnotempty(cookie->data)) {
  275.     char BIGSTK line[8192];
  276.     FILE* fp = fopen(fconv(catbuff,name),"wb");
  277.     if (fp) {
  278.       char* a=cookie->data;
  279.       fprintf(fp,"# HTTrack Website Copier Cookie File"LF"# This file format is compatible with Netscape cookies"LF);
  280.       do {
  281.         a+=binput(a,line,8000);
  282.         fprintf(fp,"%s"LF,line);
  283.       } while(strnotempty(line));
  284.       fclose(fp);
  285.       return 0;
  286.     }
  287.   } else
  288.     return 0;
  289.   return -1;
  290. }
  291.  
  292. // insertion chaine ins avant s
  293. void cookie_insert(char* s,char* ins) {
  294.   char* buff;
  295.   if (strnotempty(s)==0) {    // rien α faire, juste concat
  296.     strcatbuff(s,ins);
  297.   } else {
  298.     buff=(char*) malloct(strlen(s)+2);
  299.     if (buff) {
  300.       strcpybuff(buff,s);     // copie temporaire
  301.       strcpybuff(s,ins);      // insΘrer
  302.       strcatbuff(s,buff);     // copier
  303.       freet(buff);
  304.     }
  305.   }
  306. }
  307. // destruction chaine dans s position pos
  308. void cookie_delete(char* s,int pos) {
  309.   char* buff;
  310.   if (strnotempty(s+pos)==0) {    // rien α faire, effacer
  311.     s[0]='\0';
  312.   } else {
  313.     buff=(char*) malloct(strlen(s+pos)+2);
  314.     if (buff) {
  315.       strcpybuff(buff,s+pos);     // copie temporaire
  316.       strcpybuff(s,buff);         // copier
  317.       freet(buff);
  318.     }
  319.   }
  320. }
  321.  
  322. // renvoie champ param de la chaine cookie_base
  323. // ex: cookie_get("ceci est<tab>un<tab>exemple",1) renvoi "un"
  324. char* cookie_get(char *buffer,char* cookie_base,int param) {
  325.   char * limit;
  326.  
  327.   while(*cookie_base=='\n') cookie_base++;
  328.   limit = strchr(cookie_base,'\n');
  329.   if (!limit) limit=cookie_base+strlen(cookie_base);
  330.   if (limit) {
  331.     if (param) {
  332.       int i;
  333.       for(i=0;i<param;i++) {
  334.         if (cookie_base) {
  335.           cookie_base=strchr(cookie_base,'\t');       // prochain tab
  336.           if (cookie_base) cookie_base++;
  337.         }
  338.       }
  339.     }
  340.     if (cookie_base) {
  341.       if ( cookie_base < limit) {
  342.         char* a = cookie_base;
  343.         while( (*a) && (*a!='\t') && (*a!='\n')) a++;
  344.         buffer[0]='\0';
  345.         strncatbuff(buffer,cookie_base,(int) (a - cookie_base));
  346.         return buffer;
  347.       } else
  348.         return "";
  349.     } else
  350.       return "";
  351.   } else
  352.     return "";
  353. }
  354. // fin cookies
  355.  
  356.  
  357.  
  358. // -- basic auth --
  359.  
  360. /* dΘclarer un rΘpertoire comme possΘdant une authentification propre */
  361. int bauth_add(t_cookie* cookie,char* adr,char* fil,char* auth) {
  362.   char buffer[HTS_URLMAXSIZE*2];
  363.     if (cookie) {
  364.     if (!bauth_check(cookie,adr,fil)) {       // n'existe pas dΘja
  365.       bauth_chain* chain=&cookie->auth;
  366.       char* prefix=bauth_prefix(buffer,adr,fil);
  367.       /* fin de la chaine */
  368.       while(chain->next)
  369.         chain=chain->next;
  370.       chain->next=(bauth_chain*) calloc(sizeof(bauth_chain),1);
  371.       if (chain->next) {
  372.         chain=chain->next;
  373.         chain->next=NULL;
  374.         strcpybuff(chain->auth,auth);
  375.         strcpybuff(chain->prefix,prefix);
  376.         return 1;
  377.       }
  378.     }
  379.   }
  380.   return 0;
  381. }
  382.  
  383. /* tester adr et fil, et retourner authentification si nΘcessaire */
  384. /* sinon, retourne NULL */
  385. char* bauth_check(t_cookie* cookie,char* adr,char* fil) {
  386.   char buffer[HTS_URLMAXSIZE*2];
  387.   if (cookie) {
  388.     bauth_chain* chain=&cookie->auth;
  389.     char* prefix=bauth_prefix(buffer,adr,fil);
  390.     while(chain) {
  391.       if (strnotempty(chain->prefix)) {
  392.         if (strncmp(prefix,chain->prefix,strlen(chain->prefix))==0) {
  393.           return chain->auth;
  394.         }
  395.       }
  396.       chain=chain->next;
  397.     }
  398.   }
  399.   return NULL;
  400. }
  401.  
  402. char* bauth_prefix(char *prefix,char* adr,char* fil) {
  403.   char* a;
  404.   strcpybuff(prefix,jump_identification(adr));
  405.   strcatbuff(prefix,fil);
  406.   a=strchr(prefix,'?');
  407.   if (a) *a='\0';
  408.   if (strchr(prefix,'/')) {
  409.     a=prefix+strlen(prefix)-1;
  410.     while(*a != '/') a--;
  411.     *(a+1)='\0';
  412.   }
  413.   return prefix;
  414. }
  415.